package com.matrix.math;

public class Vector implements MathObject
{
	private String name;
	private String TAG;	
	private double i, j, k;
	
	public Vector()
	{
		this.name = "";
		this.TAG = "Vector";
		this.i = 0;
		this.j = 0;
		this.k = 0;
	}
	
	public Vector(String that, double[] what) throws Exception
	{
		this.name = that;
		this.TAG = "Vector";
		this.setData(what);
	}
	
	public Vector clone()
	{
		double[] v = {i,j,k};
		try {
			return new Vector("", v);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * addVector()
	 * Adds vector a to vector b
	 * NOTE: format for vectors is a[ix,jy,kz]
	 * @param a, b
	 * @return double the sum of the vectors a and b
	 */
	public double[] addVector(double[] a,double[] b) throws Exception
	{
		//get the vectors sizes as well as create the final sum
		int sizeA = a.length;
		int sizeB = b.length;
		double temp1=0;
		double[] sum = new double[3];
		
		//make sure vectors are the same size
		if(sizeA != sizeB)
		{
			throw new Exception("Vectors are not the same size");
		}//endif
		
		//makesure vectors the right size
		if(sizeA < 2 && sizeB < 2)
		{
			throw new Exception("Vectors have less than 3 values");
		}//endif
		
		if(sizeA > 3 && sizeB > 3)
		{
			throw new Exception("Vectors have more than 3 values");
		}//endif
		
		//add the two double arrays
		for(int i = 0;i < sizeA; i++)
		{
			//add the values individually
			temp1 = a[i]+ b[i];
			
			//round the sum to 2 decimal places
			//temp1 = Math.round(100 * temp1)/100.0;
			
			sum[i] = temp1;
		}//endfor
		
		
		
		return sum;
	}//end addvector
	
	
	/**
	 * dotProduct()
	 * Finds the scalar product of the two coordinate vectors
	 * NOTE: format for vectors is a[ix,jy,kz]
	 * @param double[] a, double[] b
	 * @return double, the scalar output of the dot product
	 */
	public double dotProduct(double[] a,double[] b) throws Exception
	{
		//set up variables
		int sizeA = a.length;
		int sizeB = b.length;
		double temp=0;
		double ans=0;
		
		//make sure vectors are the same size
		if(sizeA != sizeB)
    {
			throw new Exception("Vectors are not the same size");
		}//endif
		
		
		
		//find dot product of vectors
		for(int i = 0;i < sizeA; i++)
		{
			//multiply the values individually then add to product
			temp += a[i]* b[i];
			
			ans = temp;
		}//endfor
		
		
		
		return ans;
	}//enddotproduct
	
	
	/**
	 * magnitude()
	 * Finds the magnitude of the vector
	 * NOTE: format for vectors is a[ix,jy,kz]
	 * @param double[] a
	 * @return double ans
	 */
	public double magnitude(double[] a) throws Exception
	{
		//set up variables
		int sizeA = a.length;
		double temp=0;
		double ans; 
      
      
		for(int i = 0;i < sizeA; i++)
		{
			//square the values individually then add total
			temp += a[i]* a[i];
			
		}//endfor
		
		ans = Math.sqrt(temp);
	
		
		return ans;
	}//endmagnitude

	/** double crossProduct(double[] a, double[] b)
 	 * NOTE: format for vectors is a[ix,jy,kz]
 	 * @param double[] a, double[] b
 	 * @return double[] result 
 	 */
	public double[] crossProduct(double[] a, double[] b) throws Exception
	{
		//finds the sizes of the vectors
		int sizeOfA = a.length;
		int sizeOfB = b.length;
	
		//variable to hold the result
		double result[] = new double[3];
	
		//temporary variables used for rounding
		double temp0;
		double temp1;
		double temp2;
	
		//checks to see if the sizes of the vectors are the same
		if(sizeOfA != sizeOfB)
		{
			throw new Exception("The vectors are not the same size");
		}//end if
	
		//checks the size of 'a' to see if it is equal to 3.
		if(sizeOfA != 3)
		{
			throw new Exception("The size of the vector must be 3");
		}//end if
	
		//checks the size of 'b' to see if it is equal to 3.
		if(sizeOfB != 3)
		{
			throw new Exception("The size of the vector must be 3");
		}//end if
	
		//computes the cross product of the two vectors and places the results
		//in the proper place. Temp1 needs to be negative.
		temp0 = a[1] * b[2] - a[2] * b[1];
		temp1 = (a[0] * b[2] - a[2] * b[0]) * -1;
		temp2 = a[0] * b[1] - a[1] * b[0];
	
		//Places the temporary variables into the proper locations
		result[0] = temp0;
		result[1] = temp1;
		result[2] = temp2;
	
		return result;
	}//end crossProduct

	/*multiplies a constant by a vector 
	 *@param double [] a, double b 
	 *@return result[] 
	 */ 
	public double[] multiplyByConstant(double [] a, double b ){ 
		//variables to be used in the for loop 
		int sizeA = a.length; 
		double [] result = new double[sizeA]; 
		//multiplies each element by a constant and assigns it to result[] 
		for(int i = 0; i < sizeA; ++i ){ 
			result[i] = a[i] * b; 

		} 
		return result; 

	}//end multiplyByConstant 

	/**method to find the projection of a vector with respect to another vector 
	 * @param double [] a, double [] b 
	 * @return finalResult[] 
	 */ 
	public double [] projection(double [] a, double [] b) throws Exception{ 
		//variables used to check length of the vectors 
		int sizeA = a.length; 
		int sizeB = b.length; 
		//variables used to store the pieces of the projection formula 
		double dotProductResult; 
		double magnitudeResult; 
		double [] result = new double [3]; 
		double temp1 = 0; 

		//checks to see if the vectors have the same length 
		if(sizeA != sizeB){ 
			throw new Exception("Vectors are not the same size"); 
		} 
		//computes the dotProduct and stores it in dotProductResult 
		dotProductResult = dotProduct(a,b); 
		//computes the magnitude and stores it in a double variable 
		magnitudeResult = magnitude(b); 
		//loop that multiplies the result from the previous step by the 
		//vector of b and stores it in a finalResult variable. 
		for(int i = 0; i < sizeA; ++i){ 
			temp1 = dotProductResult * b[i]/magnitudeResult; 
			result[i] = temp1; 
		} 
		return result; 
	}


	/**
	 * setters and getters
	 */
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getTag() {
		return TAG;
	}
	public void setTAG(String tAG) {
		TAG = tAG;
	}
	
	public void setData(double[] data) throws Exception
	{
		if(data.length > 3)
		{
			throw new Exception("More than 3 componenets");
		}
		else
		{
			this.i = data[0];
			this.j = data[1];
			this.k = data[2];
		}
	}
	public double[] getData()
	{
		double[] re = new double[3];
		re[0] = this.i;
		re[1] = this.j;
		re[2] = this.k;
		return re;
	}
	
	@Override
	public String getInfo()
	{
		String s = this.getName() + " : <"+i+"i, "+j +"j, "+k+"k>";
		return s;
	}
	

	public String toString()
	{
		String s = this.getName() + " : <"+i+"i, "+j +"j, "+k+"k>";
		return s;
	}
}
